//********************************************//
//****      SEARCHING EFFORT FUNCTION      ***//
//********************************************//


/////////////////////////////////
////  PROBABILITY FUNCTIONS  ////
/////////////////////////////////

double piE(double searchval){return (1.0-exp(-kappaE*(searchval)));}
double piW(double searchval){return (1.0-exp(-kappaW*(searchval)));}




//////////////////////////////////
///////// FONCTION SEARCH ////////
//////////////////////////////////

double searchWfun(const double xval, void * params){
    struct searchEorWstruct *focparamsW= (struct searchEorWstruct *) params;
    double diffValueNext=focparamsW->diffValueNextfoc;
    int tgridfoc=focparamsW->tgridparXX;
    return (kappaW*exp(-kappaW*xval)*diffValueNext-dsearchdesutilityW(xval));
}


double searchEfun(const double xval, void * params){
    struct searchEorWstruct *focparamsE= (struct searchEorWstruct *) params;
    double diffValueNext=focparamsE->diffValueNextfoc;
    return (kappaE*exp(-kappaE*xval)*diffValueNext-dsearchdesutilityE(xval));
}


double searchEwithWgivenfun(const double seval, void * params){
    struct searchEorWstruct *focparamsWforE= (struct searchEorWstruct *) params;
    double Pswval=focparamsWforE->Psw;
    return (exp(-kappaE*seval) - dsearchdesutilityE(seval)/(betapar*kappaE*Pswval));
}


double searchWwhenEknownfun(const double swval, void * params){
    struct searchfocWwhenE *focparamsWwhenE= (struct searchfocWwhenE *) params;

    double tempUiNE=focparamsWwhenE->tempUiNEval;
    double tempUnNE=focparamsWwhenE->tempUnNEval;
    double tempWWNE=focparamsWwhenE->tempWWNEval;
    
    double tempUiE=focparamsWwhenE->tempUiEval;
    double tempUnE=focparamsWwhenE->tempUnEval;
    double tempWWE=focparamsWwhenE->tempWWEval;
    
    double tempUiNE_JNE=focparamsWwhenE->tempUiNE_JNEval;
    double tempUnNE_JNE=focparamsWwhenE->tempUnNE_JNEval;
    double tempWWNE_JNE=focparamsWwhenE->tempWWNE_JNEval;

    double tempUiE_JE=focparamsWwhenE->tempUiE_JEval;
    double tempUnE_JE=focparamsWwhenE->tempUnE_JEval;
    double tempWWE_JE=focparamsWwhenE->tempWWE_JEval;
    
    #if SEA == 1
    double tempUiE_JEi=focparamsWwhenE->tempUiE_JEival;
    double tempUiNE_JNEi=focparamsWwhenE->tempUiNE_JNEival;
    double tempWWE_JEi=focparamsWwhenE->tempWWE_JEival;
    double tempWWNE_JNEi=focparamsWwhenE->tempWWNE_JNEival;
    #endif
    
    int tgridfoc=focparamsWwhenE->tgridparXX;
    int igridfoc=focparamsWwhenE->igridparXX;
    int typeUval=focparamsWwhenE->typeUU;
    int excluded=focparamsWwhenE->excludedU;
    
    
    double diffValueNext, residu, searcheffJ, diffValue, diffgrid, ddiffgrid;
    int idiffgrid, iverif;


    /////////////////////////////////////////////////////////////////////////////////
    // FIND THE OPTIMAL EFFORT LEVEL FOR Se for given Sw (BELOW IS CALCULATED Psw) //
    /////////////////////////////////////////////////////////////////////////////////
    
    if(excluded == 1) { // if excluded from the financial market.
        if(typeUval == 0) { // if insured
        #if NOPOLICY == 1 || SUBSIDY == 1
            diffValue = max(0.000000001,(phipar)*(piW(swval)*(tempWWNE_JNE - tempWWNE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiNE_JNE + pLTpar*tempUnNE_JNE) - ((1.0-pLTpar)*tempUiNE + pLTpar*tempUnNE))) + (1.0 - phipar)*(piW(swval)*(tempWWE_JE - tempWWE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiE_JE + pLTpar*tempUnE_JE) - ((1.0-pLTpar)*tempUiE + pLTpar*tempUnE))));
        #endif
        
        #if SEA == 1
            diffValue = max(0.000000001,(phipar)*(piW(swval)*(((1.0 - pLTpar)*tempWWNE_JNEi + pLTpar*tempWWNE_JNE) - tempWWNE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiNE_JNEi + pLTpar*tempUnNE_JNE) - ((1-pLTpar)*tempUiNE + pLTpar*tempUnNE))) + (1.0 - phipar)*(piW(swval)*(((1.0 - pLTpar)*tempWWE_JEi + pLTpar*tempWWE_JE) - tempWWE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiE_JEi + pLTpar*tempUnE_JE) - ((1.0-pLTpar)*tempUiE + pLTpar*tempUnE))));
        #endif
        }
        if(typeUval == 1) { // if not insured
            diffValue = max(0.000000001,(phipar)*(piW(swval)*(tempWWNE_JNE - tempWWNE) + (1.0 - piW(swval))*(tempUnNE_JNE - tempUnNE)) + (1.0 - phipar)*(piW(swval)*(tempWWE_JE - tempWWE) + (1.0 - piW(swval))*(tempUnE_JE - tempUnE)));
        }
    }
    
    if(excluded == 0) {
        if(typeUval == 0) { // if insured
        #if NOPOLICY == 1 || SUBSIDY == 1
            diffValue = max(0.000000001,piW(swval)*(tempWWNE_JNE - tempWWNE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiNE_JNE + pLTpar*tempUnNE_JNE) - ((1-pLTpar)*tempUiNE + pLTpar*tempUnNE)));
        #endif
        
        #if SEA == 1
            diffValue = max(0.000000001,piW(swval)*(((1.0 - pLTpar)*tempWWNE_JNEi + pLTpar*(tempWWNE_JNE)) - tempWWNE) + (1.0 - piW(swval))*(((1.0-pLTpar)*tempUiNE_JNEi + pLTpar*tempUnNE_JNE) - ((1-pLTpar)*tempUiNE + pLTpar*tempUnNE)));
        #endif
        }
        if(typeUval == 1) { // if not insured
            diffValue = max(0.000000001,piW(swval)*(tempWWNE_JNE - tempWWNE) + (1.0 - piW(swval))*(tempUnNE_JNE - tempUnNE));
        }
    }
    

    // ON THE GRID REDEFINITION //
    diffgrid = invexpspace(diffValue,gridminsearch,gridmaxsearch,EchelleW,maxsearch);
    ddiffgrid = weightinter(diffValue, diffgrid, &idiffgrid, diffvalues, maxsearch);


    searcheffJ = inter1d(ddiffgrid,search2D_E[idiffgrid],search2D_E[idiffgrid+1]); // optimal Se effort given Sw.
    
    

    //////////////////////////////
    // COMPUTE DIFFVALUE FOR Sw //
    //////////////////////////////
    
    focparamsWwhenE->searchJoutST=searcheffJ;
    
    // Given the best SEval, find the best SWval function //
    if(excluded == 0) { // if not excluded from the financial market.
        if(typeUval == 0) { // if insured
        #if NOPOLICY == 1 || SUBSIDY == 1
            diffValueNext = max(0.000000000001,(betapar*((1.0 - piE(searcheffJ))*(tempWWNE - ((1.0-pLTpar)*tempUiNE + pLTpar*tempUnNE))+piE(searcheffJ)*(tempWWNE_JNE - ((1.0-pLTpar)*tempUiNE_JNE + pLTpar*tempUnNE_JNE)))));
        #endif
        
        #if SEA == 1
            diffValueNext = max(0.000000000001,(betapar*((1.0 - piE(searcheffJ))*(tempWWNE - ((1.0-pLTpar)*tempUiNE + pLTpar*tempUnNE))+piE(searcheffJ)*(((1.0 - pLTpar)*tempWWNE_JNEi + pLTpar*tempWWNE_JNE) - ((1.0-pLTpar)*tempUiNE_JNEi + pLTpar*tempUnNE_JNE)))));
        #endif
        }
        if(typeUval == 1) { // if not insured
            diffValueNext = max(0.000000000001,(betapar*((1.0 - piE(searcheffJ))*(tempWWNE - tempUnNE)+piE(searcheffJ)*(tempWWNE_JNE - tempUnNE_JNE))));
        }
    }
    
    if(excluded == 1) { // if excluded from the financial market.
        if(typeUval == 0) {
        #if NOPOLICY == 1 || SUBSIDY == 1
            diffValueNext = max(0.000000000001,(betapar*(phipar*((1.0 - piE(searcheffJ))*(tempWWNE - ((1.0-pLTpar)*tempUiNE + pLTpar*tempUnNE))+piE(searcheffJ)*(tempWWNE_JNE - ((1.0-pLTpar)*tempUiNE_JNE + pLTpar*tempUnNE_JNE))) + (1.0 - phipar)*((1.0 - piE(searcheffJ))*(tempWWE - ((1.0-pLTpar)*tempUiE + pLTpar*tempUnE))+piE(searcheffJ)*(tempWWE_JE - ((1.0-pLTpar)*tempUiE_JE + pLTpar*tempUnE_JE))))));
        #endif
        
        #if SEA == 1
            diffValueNext = max(0.000000000001,(betapar*(phipar*((1.0 - piE(searcheffJ))*(tempWWNE - ((1.0-pLTpar)*tempUiNE + pLTpar*tempUnNE))+piE(searcheffJ)*(((1.0 - pLTpar)*tempWWNE_JNEi + pLTpar*tempWWNE_JNE) - ((1.0-pLTpar)*tempUiNE_JNEi + pLTpar*tempUnNE_JNE))) + (1.0 - phipar)*((1.0 - piE(searcheffJ))*(tempWWE - ((1.0-pLTpar)*tempUiE + pLTpar*tempUnE))+piE(searcheffJ)*(((1.0 - pLTpar)*tempWWE_JEi + pLTpar*tempWWE_JE) - ((1.0-pLTpar)*tempUiE_JEi + pLTpar*tempUnE_JE))))));
        #endif
        }
        if(typeUval == 1) {
            diffValueNext = max(0.000000000001,(betapar*(phipar*((1.0 - piE(searcheffJ))*(tempWWNE - tempUnNE)+piE(searcheffJ)*(tempWWNE_JNE - tempUnNE_JNE)) + (1.0 - phipar)*((1.0 - piE(searcheffJ))*(tempWWE - tempUnE)+piE(searcheffJ)*(tempWWE_JE - tempUnE_JE)))));
        }
    }
    
    residu = kappaW*exp(-kappaW*swval)*diffValueNext-dsearchdesutilityW(swval);
    
    return residu;
}


